/*
 *  Copyright 2009 Jamie Gennis <jgennis@gmail.com>.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */

package com.google.code.gwt.remoteaction.group.client;

import com.google.gwt.user.client.rpc.AsyncCallback;

/**
 * An object capable of grouping multiple action invocations together and
 * notifying a callback object once either all actions have successfully
 * completed or one of the actions has failed.
 * 
 * @author jgennis
 */
public interface ActionGrouper {

  /**
   * Begin a new action group.
   * 
   * The action group consists of all the actions invoked through this {@code
   * ActionGrouper} in between the call to {@code beginActionGroup} and a
   * corresponding call to {@link #endActionGroup(ActionGroup)} that is passed
   * the {@link ActionGroup} returned by {@code beginActionGroup}.
   * 
   * The specified {@code callback} object will be called once execution of the
   * action group has either succeeded or failed. If all of the actions in the
   * action group succeed then {@link AsyncCallback#onSuccess(Object)} is
   * called. If any of actions fail then
   * {@link AsyncCallback#onFailure(Throwable)} is called with the same
   * {@link Throwable} argument that is passed to the callback of the first
   * failing action invocation.
   * 
   * Note that the {@link AsyncCallback#onSuccess(Object)} method of the {@code
   * callback} instance will not be called until after
   * {@link #endActionGroup(ActionGroup)} has been called for the
   * {@link ActionGroup}, but {@link AsyncCallback#onFailure(Throwable)} may be
   * called before {@link #endActionGroup(ActionGroup)}.
   * 
   * @param callback the callback object that will be notified when execution of
   *          the action group has succeeded or failed
   * @return an opaque representation of the new action group
   * @throws IllegalArgumentException if {@code callback} is null
   */
  public ActionGroup beginActionGroup(AsyncCallback<Void> callback);

  /**
   * Stop adding action invocations to the given action group.
   * 
   * @param actionGroup the action group
   * @throws IllegalArgumentException if {@code actionGroup} was not created by
   *           a call to {@link #beginActionGroup(AsyncCallback)} on this
   *           {@code ActionGrouper}
   */
  public void endActionGroup(ActionGroup actionGroup);
}
